# coding=utf8
__author__ = 'lijian'
import manager
import math
import logging
from protocol.term import *
import monitor
from utils import byteUtil

import threading

plcLock = threading.RLock()

_actionDict = {
    0: 0x61,
    1: 0x62,
    2: 0x63
}

_monitor = monitor.Monitor.GetInstance()


def toTermLevel(optType, value):
    action = _actionDict[optType]
    if action == 0x61:
        level = 0x14
    elif action == 0x62:
        level = 0
    else:
        level = int(math.floor(value / 12.75))  # 调光值转为0-20档

    return action, level


def pointCtrl(holderNo, optType, value):
    holder = manager.findHolder(holderNo)
    if holder:

        action, level = toTermLevel(optType, value)

        # data = [action, level]
        # packet = Packet(ctrl.UNI_CAST, data, term.uid)
        # _monitor.send(packet)

        if action == 0x61:
            holder.mockPowerOn()
        elif action == 0x62:
            holder.mockPowerOff()

        return True
    else:
        return False


def groupCtrl(groupNo, optType, value):
    action, level = toTermLevel(optType, value)

    logging.info("group %d ctrl,action:%02x,level:%02x" % (groupNo, action, level))

    lightValueBytes = [0, 0, 0, level]

    terms = manager.findTermByGroup(groupNo)
    holders = []
    for term in terms:
        for holder in term.holders:
            holders.append(holder)

    data = []
    maxMaskNum = manager.getMaxHolderNo()

    lampByteLength = maxMaskNum / 4
    if maxMaskNum % 4 != 0:
        lampByteLength += 1

    data.append(0)  # 子网号
    data.append(lampByteLength)

    maskData = [0] * lampByteLength

    for holder in holders:
        offset = (4 - (holder.holderNo % 4)) * 2
        lightValueIndex = 3
        if offset < 8:
            lampPlace = lightValueIndex << offset
        else:
            lampPlace = lightValueIndex

        index = (holder.holderNo - 1) / 4
        byte = maskData[index]
        byte = byte | lampPlace
        maskData[index] = byte

    data.extend(maskData)
    data.extend(lightValueBytes)
    data.append(0x60)

    packet = Packet(0x42, data)
    _monitor.send(packet, [0, 0, 0, 0, 0, 0])

    return True


def broadcastCtrl(optType, value):
    plcLock.acquire()
    action, level = toTermLevel(optType, value)
    logging.info("broadcastCtrl,action:%02x,level:%02x" % (action, level))
    data = [action, level]
    packet = Packet(ctrl.BROADCAST, data)
    _monitor.send(packet, [0, 0, 0, 0, 0, 0])

    plcLock.release()
    return True


def broadcastSnapshot():
    terms = manager.getAllTerms()

    for term in terms:
        term.hasSnapshot = True
